﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.Xml;

namespace Common.Xml.Serialization
{
    [XmlRoot(Namespace = "http://www.w3.org/", ElementName = "directory")]
    public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
    {
        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(XmlReader reader)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            reader.Read();

            if (reader.IsEmptyElement) return;

            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item"); // <item>

                reader.ReadStartElement("key"); // <key>
                TKey key = (TKey)keySerializer.Deserialize(reader);
                reader.ReadEndElement(); // </key>

                reader.ReadStartElement("value"); // <value>
                TValue value = (TValue)valueSerializer.Deserialize(reader);
                reader.ReadEndElement(); // </value>

                this.Add(key, value);

                reader.ReadEndElement(); // </item>
                reader.MoveToContent();
            }

            reader.ReadEndElement();
        }

        public void WriteXml(XmlWriter writer)
        {
            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            foreach (TKey key in this.Keys)
            {
                writer.WriteStartElement("item"); // <item>
                
                writer.WriteStartElement("key"); //<key>
                keySerializer.Serialize(writer, key);
                writer.WriteEndElement(); //</key>

                writer.WriteStartElement("value"); //<value>
                object value = this[key];
                valueSerializer.Serialize(writer, value);
                writer.WriteEndElement();// </value>

                writer.WriteEndElement(); // </item>
            }
        }
    }
}
